Nek izdelek naj bi se vsak teden podražil za 2%. Da bi razumeli, kaj to
pomeni, napiši funkcijo kolikoTednov(cena)
, ki za dano začetno ceno (v €)
tega izdelka vrne število tednov, ko bo cena dosegla ali presegla 1000€.
V dobrih 6 letih bi se to zgodilo s kavo, ki sedaj stane 1€!
Za šaljivce, ki bodo funkcijo poklicali z negativno ceno, vrni -1
def kolikoTednov(cena): ''' v koliko tednih se ob 2% tedenski podražitvi cena dvigne nad 1000€''' končnaCena = 1000 trenutnaCena = cena tednov = 0 if trenutnaCena < 0: return -1 while trenutnaCena < končnaCena: trenutnaCena = trenutnaCena * 1.02 tednov += 1 # to je isto kot tednov = tednov + 1 return tednov
Bakteriolog Bine preučuje bakterije. Naredil je sledeči poizkus: bakterije je zaprl v škatlico pravokotne oblike s pregrado na sredini, ki razdeli škatlico na dva kvadratna dela - poimenujmo ju regija A in regija B. Zunanje stene te škatlice so polprepustne, kar pomeni, da bacili lahko uidejo ven, vendar se ne morejo vrniti v škatlico, pregrada pa je prepustna, tj. bacili lahko prehajajo v obe smeri. Bine predvideva, da v neki časovni enoti 12 % vseh bacilov ostane v svoji regiji, po 22 % pa jih zapusti svojo regijo v vsaki od štirih smeri. Binetu sestavi program, ki bo prebral začetni masi bacilov (bacili so premajhni, da bi jih # šteli posamično, zato jih "štejemo" kar v gramih) v vsaki od regij in izpisal število korakov, dokler skupna masa bacilov v obeh regijah ne pade pod 0.001 grama. Tako bo lahko Bine primerjal teoretični izračun z izmerjenimi podatki in preveril svojo hipotezo. Predpostavi, da so podatki pravilni (nenegativni!
Pozor! Premisli, kaj se dogaja na pregradi!
Za začetni masi 22.4 in 13.5 se število bakterij giblje
1, 5.658, 6.548
2, 2.11952, 2.03052
3, 0.7010568, 0.7099568
4, 0.240317312, 0.239427312
5, 0.08151208608, 0.08160108608
6, 0.0277336892672, 0.0277247892672
7, 0.00942749635085, 0.00942838635085
8, 0.00320554455929, 0.00320545555929
9, 0.00108986557016, 0.00108987447016
10 0.0003035929996319583 0.0003035829997319583
zato bi program izpisal 10. Primer:
>>>Masa v regiji A: 22.4
Masa v regiji B: 13.5
Korakov: 10
# Določimo število tednov, ko se ustrezno zmanjša začetna porazdelitev bakterij masaA = float(input('Masa v regiji A: ')) masaB = float(input('Masa v regiji B: ')) korak = 0 while masaA + masaB >= 0.001: # skupna teža je še prevelika staraA = masaA # potrebovali bomo za izračun B-ja masaA = masaA * 0.12 # toliko jih ostane masaA = masaA + masaB * 0.22 # toliko jih pa še pride iz B masaB = masaB * 0.12 masaB = masaB + staraA * 0.22 korak += 1 # en korak več print('Korakov:', korak)
Sestavite funkcijo vsotaKvadratov(n)
, ki izračuna in vrne vsoto
>>> vsotaKvadratov(10)
385
def vsotaKvadratov(n): '''Vsota kvadratov''' s = 0 for i in range(1, n + 1): # začnemo pri 1 in končamo pri n s += i * i return s def vsotaKvadratovMat(n): '''No, če ste malo bolj "doma" v matematiki, je vaša rešitev seveda ''' return n * (n + 1) * (2*n + 1) // 6
Sestavite funkcijo vsota(n)
, ki izračuna in vrne vsoto
>>> vsota(10)
440
def vsota(n): '''Vsota vrste ''' s = 0 for i in range(1, n + 1): # začnemo pri 1 in končamo pri n s += i * (i + 1) return s
Sestavite funkcijo stevilo_clenov(m)
, ki izračuna, največ koliko
členov vsote m
.
Primer:
>>> stevilo_clenov(20)
3
def stevilo_clenov(m): '''Koliko členov vrste lahko seštejemo, da ne presežemo meje m''' vsotaVrste = 0 if m < 1: # ne smemo sešteti nobenega return 0 stČlenov = 0 while vsotaVrste <= m: stČlenov += 1 vsotaVrste += stČlenov * (stČlenov + 1) return stČlenov - 1 # z zadnjim smo že presegli mejo
Sestavite funkcijo najblizje(a, b, m)
, ki poišče takšno število k
med a
in b
, pri katerem se z eno od delnih vsot
m
. Če je takšnih števil več, naj funkcija
vrne najmanjšega. Primer:
>>> najblizje(10, 20, 10000)
14
def blizina(k, m): '''Kako najbližje se lahko z $k\cdot(k+1) + (k+1)\cdot(k+2) + (k+2)\cdot(k+3) + \ldots$ približamo meji m ''' sZgoraj = 0 while sZgoraj <= m: # nehali bomo, ko bomo presegli mejo sZgoraj += k * (k + 1) k += 1 sSpodaj = sZgoraj - (k - 1) * k # če se ustavimo prej, še ne presežemo m return min(sZgoraj - m, m - sSpodaj) # ali smo se meji bolj približali od spodaj, ali od zgoraj def najblizje(a, b, m): '''Kje med a in b moramo začeti sešetvati člene vrste, da se najbolj približamo meji m''' najmanRaz, najK = blizina(a, m), a # kandidat je a for k in range(a + 1, b + 1): # še preostale razdalja = blizina(k, m) if razdalja < najmanRaz: # našli smo boljšega kandidata najmanRaz = razdalja najK = k return najK
Sestavi funkcijo obrniStevilo(n)
, ki obrne pozitivno celo število.
Iz 234 torej naredi število 432. Če je podatek slučajno negativen, vrni 0!
Tisti, ki že poznate funcije in metode za delo z nizi, teh prijemov tukaj ne smete uporabiti. V tej nalogi torej nikjer ne smemo uporabljati nizov!
def obrniStevilo(n): ''' Funkcija obrne pozitivno celo število''' if n < 0: return 0 obrnjeno = 0 while n > 0: obrnjeno = obrnjeno * 10 + n % 10 n = n // 10 return obrnjeno
Najprej si oglej naslednjo funkcijo. Ugotovi, kaj počne! Očitno jo je pisal nek programer začetnik, kar lahko zlahka ugotovimo po odsotnosti komentarjev in izbiri imen spremenljivk
def f(a, b):
d = a % b # koliko še ostane
k = 0
r = '.'
while k <= 10:
d = d * 10
nd = d // b
r = r + str(nd)
k = k + 1
d = d % b
return r
Namig: pokliči jo s parametri 7, 3; 2, 4; 15, 7; 1, 3; 2, 3; 3, 3 in poskusi postaviti hipotezo, kaj se dogaja ...
Oborožen z vedenjem o zgornji funkciji
sestavi funkcijo kvocient(a, b, n)
, ki bo vrnila celi del in prvih n decimalk
kvocienta a/b v obliki niza.
Delaj samo s pozitivnimi celimi števili in na koncu NE zaokrožuj
>>>kvocient(10, 761, 40)
0.0131406044678055190538764783180026281208
>>>kvocient(100, 3, 14)
33.33333333333333
Namig: kako delimo "peš"?
def kvocient(a, b, n): '''Izračunamo a/b na n decimalk (za dec. piko)''' celiDel = a // b rezultat = str(celiDel) + '.' delimo = a % b # koliko še ostane decimalke = 0 while decimalke < n: # koliko decimalk potrebujemo delimo = delimo * 10 novaDec = delimo // b rezultat = rezultat + str(novaDec) # dodamo decimalko decimalke = decimalke + 1 # je ena več delimo = delimo % b # za naslednji korak return rezultat
Programer Mihec je sestavil funkcijo vsebuje(a, k)
, ki naj bi povedala
(True/False) če poljubno celo število a
vsebuje števko k.
def vsebuje(stevilo, k):
''' ali število stevilo vsebuje števko k '''
while stevilo > 0:
if stevilo % 10 == k:
return True
stevilo = stevilo // 10
return False
Preizkusil jo je na storitvi Projekt Tomo, a je kar naprej dobival obvestila o napačnem rezultatu. Preizkusi jo še ti in jo ustrezno popravi!
def vsebuje(stevilo, k): ''' ali število stevilo vsebuje števko k ''' if stevilo == k == 0 : return True stevilo = abs(stevilo) # zaradi neg. števil! while stevilo > 0: if stevilo % 10 == k: return True stevilo = stevilo // 10 return False
Sestavi funkcijo prestejVsebuje(a,b,k)
, ki prešteje,
koliko števil med a
in b
(meji vključeni)
vsebuje števko k.
A pozor, lahko je tudi a
>= b
def prestejVsebuje(a, b, k): ''' prešteje koliko je med a in b števil, ki vsebujejo števko k ''' mini = min(a, b) maksi = max(a, b) stevilo = mini koliko = 0 # koliko jih zadošča pogoju while stevilo <= maksi: if vsebuje(stevilo, k): koliko += 1 stevilo = stevilo + 1 return koliko
Sestavi funkcijo prestejPrave(a,b,k)
, ki prešteje,
koliko števil med a
in b
(0 <= a
<= b
), meji vključeni,
vsebuje števko k ali pa so ona ali pa njihovi obrati deljivi s k.
def vsebuje(stevilo, k): ''' ali število stevilo vsebuje števko k ''' if stevilo == k == 0 : return True while stevilo > 0: if stevilo % 10 == k: return True stevilo = stevilo // 10 return False def obrniStevilo(n): ''' Funkcija obrne pozitivno celo število''' obrnjeno = 0 while n > 0: obrnjeno = obrnjeno * 10 + n % 10 n = n // 10 return obrnjeno def prestejPrave(a, b, k): ''' prešteje koliko je med a in b števil, ki zadoščajo pogoju k ''' stevilo = a koliko = 0 # koliko jih zadošča pogoju while stevilo <= b: if vsebuje(stevilo, k) or stevilo % k == 0 or obrniStevilo(stevilo) % k == 0: koliko += 1 stevilo = stevilo + 1 return koliko
Pravimo, da sta števili
Približek števila
Sestavite funkcijo naslednjiPriblizek(x)
, ki iz približka x
po
zgornjem postopku izračuna naslednji približek števila
def naslednjiPriblizek(x): '''Naslednji približek za zlati rez''' return 1 + 1 / x
Sestavite funkcijo priblizek(k)
, ki izračuna k
. približek števila
k
enak
def priblizek(k): '''K-ti približek za zlati rez, če začnemo z 1''' x = 1 poskus = 1 #kateri člen zaporedja while poskus <= k: x = naslednjiPriblizek(x) poskus += 1 return x
Sestavite funkcijo natancniPriblizek(eps)
, ki izračuna prvi približek
števila eps
.
def natancniPriblizek(eps): '''Približek, ki se od prejšnjega razlikuje za manj kot eps (začnemo z 1)''' prejsnji = 1 naslednji = naslednjiPriblizek(prejsnji) while abs(prejsnji - naslednji) >= eps: prejsnji = naslednji # zadnji je za naslednji korak prejšnji naslednji = naslednjiPriblizek(prejsnji) return naslednji
Približke za kvadratni koren števila
Sestavite funkcijo priblizek(n, k)
, ki po zgornjem postopku izračuna
k
. približek korena števila n
.
def priblizek(n, k): '''K-ti približek za kvadratni koren''' trenutniPrib = n / 2 i = 0 while i < k: trenutniPrib = (trenutniPrib + n / trenutniPrib) / 2 i = i + 1 return trenutniPrib
Sestavite funkcijo koren(n, eps)
, ki po zgornjem postopku izračuna
prvi približek korena števila n
, za katerega se kvadrat približka od n
razlikuje za manj kot eps
. Smislena vrednost za argument eps
je npr.
def koren(n, eps): '''Približek za koren na eps natančno''' priblizek = n / 2 while abs(priblizek ** 2 - n) > eps: priblizek = (priblizek + n / priblizek) / 2 return priblizek